home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / DataScope 2.0.3 / DataScope2l / DSSource / fview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  39.7 KB  |  1,724 lines  |  [TEXT/MPS ]

  1. # include <types.h>                 /* Nearly always required */
  2. # include <quickdraw.h>             /* To access the qd globals */
  3. # include <toolutils.h>             /* CursHandle and iBeamCursor */
  4. # include <fonts.h>                 /* Only for InitFonts() trap */
  5. # include <events.h>                /* GetNextEvent(), ... */
  6. # include <windows.h>                /* GetNewWindow(), ... */
  7. # include <controls.h>
  8. # include <files.h>
  9. # include <fcntl.h>
  10. # include <packages.h>
  11. # include <dialogs.h>                /* InitDialogs() and GetNewDialog() */
  12. # include <menus.h>                 /* EnableItem(), DisableItem() */
  13. # include <desk.h>                    /* SystemTask(), SystemClick() */
  14. # include <textedit.h>                /* TENew() */
  15. # include <scrap.h>                 /* ZeroScrap() */
  16. # include <StdIO.h>
  17. # include <Math.h>
  18. # include <OSEvents.h>
  19. # include <Palette.h>
  20. #include    <Resources.h>
  21. #define switchEvt     1        /* Switching event (suspend/resume )  for app4evt */
  22. /*
  23.  * Resource ID constants.
  24.  */
  25. # define appleID        128             /* This is a resource ID */
  26. # define fileID         129             /* ditto */
  27. # define editID         130             /* ditto */
  28. # define imageID        131
  29. # define numID            132
  30.  
  31. # define appleMenu        0                /* MyMenus[] array indexes */
  32. # define    MAbout_DataScope    1
  33.  
  34. # define fileMenu        1
  35. # define    MOpen         101
  36. # define    MClose        102
  37. # define    MSave         103
  38. # define    MSave_As     104
  39. # define     MLoad_Palette    106
  40. # define    MLoad_Text     107
  41. # define    MQuit         109
  42.  
  43. # define editMenu        2
  44. # define    MUndo         201
  45. # define    MCut        203
  46. # define    MCopy         204
  47. # define    MPaste        205
  48. # define    MClear        206
  49.  
  50. # define imageMenu                 3
  51. # define MGenerate_Image        301
  52. # define MImage_Size            302
  53. # define MInterpolated_Image    304
  54. # define MInterpolate_Size        305
  55. # define MPolar_Image            307
  56. # define MPolar_Size            308
  57.  
  58. # define numMenu                 4
  59. # define MAttributes            401
  60. # define MSynchronize            402
  61. # define MExtract_Selection     403
  62. # define MSee_Notebook            405
  63. # define MCalculate_From_Notes  406
  64.  
  65. # define menuCount     5
  66. # define windowID            128
  67. # define imgwinID              129
  68. /*
  69.  * For the About ... DLOG
  70.  */
  71. # define aboutMeDLOG        128
  72. # define openDLOG              131
  73. # define attrDLOG              129
  74. # define nomemDLOG          132
  75.  
  76. /*
  77. *  For the controls
  78. */
  79. #define Cnewuser             129
  80. #define Cdelete             130
  81. #define Cpasswd             131
  82. #define NCS 3
  83.  
  84. /*
  85.  * HIWORD and LOWORD macros, for readability.
  86.  */
  87. # define HIWORD(aLong)        (((aLong) >> 16) & 0xFFFF)
  88. # define LOWORD(aLong)        ((aLong) & 0xFFFF)
  89.  
  90. /*
  91.  * Global Data objects, used by routines external to main().
  92.  */
  93. MenuHandle        MyMenus[menuCount];     /* The menu handles */
  94. Boolean         DoneFlag;                /* Becomes TRUE when File/Quit chosen */
  95.  
  96. int openfloat(),loseit(),saveit(), loadtext(), 
  97.     dopaste(), makeimage(), interpit(), polarit(),
  98.     loadpal(), doatt(), dopatt(), extit(), setsynch(), dosize(),
  99.     newnotes(), calcnotes();
  100.              
  101. #include "fview.h"
  102.  
  103. struct Mwin 
  104.         *mw,                /* temporary list pointer */
  105.         *fmw,                /* Data pointer which goes along with the front window */
  106.         *Mlist;                /* Mwin list - master list of windows */
  107.         
  108.     CursHandle
  109.         spinwatch[10],        /* for time-waits */
  110.         ibeamHdl;
  111.     Rect 
  112.         tr,
  113.         screenRect;
  114.     RgnHandle 
  115.         Urgn;                /* storage for update region */
  116.     int 
  117.         MFhere=0,            /* do we have multifinder? */
  118.         synchro=0;            /* synchronization flag */
  119.     char 
  120.         *rgbsave;            /* space for default palette */
  121.         
  122.     Point 
  123.         startwin = {50,20};
  124.     
  125. int (*callme)();            /* for menu re-direction */
  126. struct Mwin *callmw;
  127.  
  128. int
  129. main()
  130. {
  131.     extern void     setupMenus();
  132.     extern void     doCommand();
  133.     Rect             dragRect;
  134.     Point            mousePt;
  135.     EventRecord     myEvent;
  136.     WindowPtr        theActiveWindow, whichWindow;
  137.     int                i,timer;
  138.     short int        shorti,shortj;
  139.     AppFile            theFile;
  140.     /*
  141.      * Initialization
  142.      */
  143.     InitGraf(&qd.thePort);
  144.     InitFonts();
  145.     InitWindows();
  146.     InitMenus();
  147.     TEInit();
  148.     InitDialogs(nil);
  149.     InitCursor();
  150.     
  151.     MaxApplZone();
  152.     MoreMasters();
  153.     MoreMasters();
  154.     MoreMasters();
  155.     MoreMasters();
  156.     
  157. /*
  158. *  check for multifinder presence.
  159. */
  160.     if (GetTrapAddress( 0x60) != GetTrapAddress( 0x9f) ) {
  161.         MFhere = 1;
  162.         WaitNextEvent(everyEvent, &myEvent, 3, 0L);
  163.         WaitNextEvent(everyEvent, &myEvent, 3, 0L);
  164.     }
  165.  
  166. /*
  167. *  Opening dialog display
  168. */
  169.     timer = TickCount() + 2000;
  170.     openingdialog(1);        /* show opening message */
  171.     setupMenus();            /* Local procedure, below */
  172.     Urgn = NewRgn();        /* for temporary update region */
  173.     
  174.  
  175.     FlushEvents(everyEvent - diskEvt, 0);
  176. /*
  177. *  get a copy of the current color set
  178. */
  179.     colorsave();
  180.     setgreys();                /* initial menu setup */
  181.     
  182.     /*
  183.      * Calculate the drag rectangle in advance.
  184.      * This will be used when dragging a window frame around.
  185.      * It constrains the area to within 4 pixels from the screen edge
  186.      * and below the menu bar, which is 20 pixels high.
  187.      */
  188.     screenRect = qd.screenBits.bounds;
  189.     SetRect(&dragRect,  4, 20 + 4, screenRect.right-4, screenRect.bottom-4);
  190.     ibeamHdl = GetCursor(iBeamCursor);        /* Grab this for use later */
  191.     for (i=0; i<7; i++)
  192.         spinwatch[i] = GetCursor(257+i);    /* grab these for later, too */
  193.     
  194. /*
  195. *  allocate and setup rgbsave
  196. */
  197.     rgbsave = (char *) NewPtr(800);
  198.     
  199.     for (i=0; i<240; i++) {
  200.         rgbsave[i*3] = i;                    /* set up grey starting values */
  201.         rgbsave[i*3+1] = i;
  202.         rgbsave[i*3+2] = i;
  203.     }
  204. /*
  205. *  for the selected files, try to load them into windows.
  206. */
  207.     Mlist = NULL;
  208.     CountAppFiles( &shorti, &shortj);
  209.     while (!shorti && shortj > 0) {
  210.         GetAppFiles( shortj, &theFile);            /* get file name */
  211.         p2cstr(theFile.fName);
  212.         setvol(NULL, theFile.vRefNum);            /* set to this volume (dir) */
  213.         getdf(theFile.fName);                    /* inserts window(s) into Mlist */
  214.         ClrAppFiles(shortj--);
  215.         timer = TickCount() + 10;                /* shorten the time to wait */
  216.     }
  217.     setgreys();                                    /* grey or un-grey the menus */
  218.  
  219. /*
  220. *  reset callme pointer
  221. */
  222.     callme = NULL;
  223. /*
  224. *  start the network 
  225. */
  226.     startnet();
  227.     
  228.     /*
  229.      * Ready to go.
  230.      * Start with a clean event slate, and cycle the main event loop
  231.      * until the File/Quit menu item sets DoneFlag.
  232.      *
  233.      */
  234. /*
  235. *  With the Opening dialog up,
  236. *  Wait for many seconds or until user presses a key or the mouse.
  237. */    
  238.     while (timer > TickCount()) {
  239.         if (EventAvail(keyDownMask + mDownMask, &myEvent)) {
  240.             if (myEvent.what == mouseDown 
  241.                 && IsDialogEvent(&myEvent))        /* eat clicks in the dialog */
  242.                 GetNextEvent(mDownMask, &myEvent);
  243.             break;                                /* go directly into program */
  244.         }
  245.     }
  246.  
  247.     openingdialog(0);                            /* take away the opening dialog */
  248.     DoneFlag = false;
  249.     for ( ;; ) {
  250.         if (DoneFlag) {
  251.             break;                                /* from main event loop */
  252.         }
  253.         /*
  254.          * Main Event tasks:
  255.          */
  256.         SystemTask();
  257.         theActiveWindow = FrontWindow();        /* Used often, avoid repeated calls */
  258.         
  259.         if (!MFhere)
  260.             i = GetNextEvent(everyEvent, &myEvent);
  261.         else
  262.             i = WaitNextEvent(everyEvent, &myEvent, 3, 0L);        /* MF only */
  263.  
  264.         if ( !i ) {
  265.              
  266. /*
  267. *  network events
  268. */
  269.             donetevents();
  270.             
  271.              if (callme) {                        /* menu selection redirection */
  272.                  (*callme)(callmw);
  273.                 callme = NULL;
  274.                 fmw = findm(FrontWindow());        /* which window is front now? */
  275.             }
  276.             else {
  277.  
  278. /*
  279. *  Cursor checking and background I-beam idling.
  280. */
  281.                 mw = Mlist;
  282.                 while (mw) {
  283.  
  284.                     if (mw->wintype == FNOTES && mw->win == theActiveWindow) {
  285.                         SetPort(mw->win);
  286.                         GetMouse(&mousePt);
  287.                         SetCursor(ptinrect(&mousePt, &mw->nw->vis) ? *ibeamHdl : &qd.arrow);
  288.                         TEIdle(mw->nw->trec);
  289.                         mw = mw->next;
  290.                     }
  291.                     else
  292.                         mw = mw->next;
  293.                 }
  294.             }
  295.             
  296.             setgreys();                            /* check menu status, grey out? */
  297.  
  298.             continue;
  299.         }
  300.         
  301.         SetCursor(&qd.arrow);
  302. /*
  303. *  main event case statement
  304. */
  305.         switch (myEvent.what) {
  306.             case mouseDown:
  307.                 switch (findwindow(&myEvent.where, &whichWindow)) {
  308.                     case inSysWindow:
  309.                         SystemClick(&myEvent, whichWindow);
  310.                         break;
  311.                     case inMenuBar:
  312.                         doCommand(menuselect(&myEvent.where));
  313.                         break;
  314.                     case inDrag:
  315.                         dragwindow(whichWindow, &myEvent.where, &dragRect);
  316.                         break;
  317.                     case inGoAway:
  318.                         GlobalToLocal(&myEvent.where);
  319.                         if (trackgoaway(whichWindow, &myEvent.where)) {
  320.                             if (mw = findm(whichWindow)) {
  321.                                 switch (mw->wintype) {
  322.                                 case FTEXT:
  323.                                     loseit(mw);
  324.                                     break;
  325.                                 case FIMG:
  326.                                     loseimage(mw);
  327.                                     break;
  328.                                 case FBI:
  329.                                     loseinterp(mw);
  330.                                     break;
  331.                                 case FPOL:
  332.                                     losepolar(mw);
  333.                                     break;
  334.                                 case FNOTES:
  335.                                     losenotes(mw);
  336.                                     break;
  337.                                 }
  338.                             }
  339.                         }
  340.                         break;
  341.                     case inGrow:
  342.                         mw = findm(whichWindow);
  343.                         if (mw && mw->wintype == FTEXT) {
  344.                             growfloat(mw, &myEvent.where);
  345.                             break;
  346.                         }
  347.                     case inContent:
  348.                         if (whichWindow != theActiveWindow) {
  349.                             SelectWindow(whichWindow);
  350.                             break;
  351.                         }
  352.                         mw = findm(whichWindow);
  353.                         if (mw) switch (mw->wintype) {
  354.                             case FTEXT:
  355.                                 mousefloat(mw, &myEvent.where, myEvent.modifiers);
  356.                                 break;
  357.                             case FIMG:
  358.                             case FBI:
  359.                                 mouseimg(mw, &myEvent.where, myEvent.modifiers);
  360.                                 break;
  361.                             case FPOL:
  362.                                 mousepol(mw, &myEvent.where, myEvent.modifiers);
  363.                                 break;
  364.                             case FNOTES:
  365.                                 SetPort(mw->win);
  366.                                 GlobalToLocal(&myEvent.where);
  367.                                 TEClick(myEvent.where, (myEvent.modifiers & shiftKey), mw->nw->trec);
  368.                                 break;
  369.                             default:
  370.                                 break;
  371.                         }
  372.                         
  373.                     default:
  374.                         break;
  375.                 }/*endsw findwindow*/
  376.                 break;
  377.  
  378.             case diskEvt:            /* check to see if disk needs to be initialized */
  379.                 mousePt.h = 100; mousePt.v = 120;
  380.                 if (noErr != (HIWORD(myEvent.message))) {
  381.                     dibadmount( &mousePt, myEvent.message );
  382.                 }
  383.                 break;
  384.                 
  385.             case keyDown:
  386.             case autoKey:
  387.                 if (myEvent.modifiers & cmdKey) {
  388.                     doCommand(MenuKey(myEvent.message & charCodeMask));
  389.                 }
  390.                 else if (fmw && fmw->wintype == FNOTES) {
  391.                     TEKey((char) (myEvent.message & charCodeMask), fmw->nw->trec);
  392.                     fmw->dat->needsave=1;            /* note change has been made */
  393.                 }
  394. #ifdef DEBUGxx
  395.                 else if ((((char)(myEvent.message & charCodeMask)) == 'W')) {    /* special window */
  396.                     /* specialdebug(fmw); */
  397.                 }
  398. #endif
  399.                 break;
  400.  
  401.             case activateEvt:
  402.                 mw = findm((WindowPtr) myEvent.message);
  403.                 if (myEvent.modifiers & activeFlag)
  404.                     fmw = mw;
  405.                 else
  406.                     fmw = NULL;
  407.                 if (mw) {
  408.                     SetCursor(&qd.arrow);
  409. /*
  410. *  set menus for TEXT or IMG window, disable/enable items
  411. */
  412.                     if (myEvent.modifiers & activeFlag) {
  413.                         Disit(MUndo);
  414.                         if (mw->wintype == FNOTES) {
  415.                             Disit(MSee_Notebook);
  416.                             Enabit(MCalculate_From_Notes);
  417.                         }
  418.                         else {
  419.                             Enabit(MSee_Notebook);
  420.                             Disit(MCalculate_From_Notes);
  421.                         }
  422.                     }
  423.                     else
  424.                         Enabit(MUndo);                            /* for DAs */
  425.  
  426.                     if (mw->wintype == FTEXT) {
  427.                         if (myEvent.modifiers & activeFlag) {
  428.                             HiliteControl(mw->cw->vbar, 0);
  429.                             HiliteControl(mw->cw->hbar, 0);
  430.                             DrawGrowIcon(mw->win);
  431.                         }
  432.                         else {
  433.                             HiliteControl(mw->cw->vbar, 255);
  434.                             HiliteControl(mw->cw->hbar, 255);
  435.                             DrawGrowIcon(mw->win);
  436.                         }
  437.                     }
  438.                     else if (mw->wintype == FNOTES) {
  439.                         if (myEvent.modifiers & activeFlag) {
  440.                             TEActivate(mw->nw->trec);
  441.                         } 
  442.                         else 
  443.                             TEDeactivate(mw->nw->trec);
  444.                     }
  445.                 }
  446.  
  447.                 break;
  448.  
  449.             case updateEvt:
  450.                 mw = findm((WindowPtr) myEvent.message);    /* find right window */
  451.                 if (mw) {
  452.                     BeginUpdate(mw->win);
  453.                     switch (mw->wintype) {
  454.                     case FTEXT:                        /* text window */
  455.                         controlfloat(mw);            /* scroll bars first, better feedback */
  456.                         drawfloat(mw,0,0);
  457.                         break;
  458.                     case FBI:
  459.                     case FPOL:
  460.                     case FIMG:                        /* image window */
  461.                         copyimg(mw);
  462.                         break;
  463.                     case FNOTES:
  464.                         SetPort(mw->win);
  465.                         EraseRect(&mw->nw->vis);
  466.                         TEUpdate(&mw->nw->vis, mw->nw->trec);
  467.                         break;
  468.                     }
  469.                     EndUpdate(mw->win);
  470.                 }
  471.                     
  472.                 break;
  473.                 
  474.             case app4Evt:
  475.                 switch(( myEvent.message >>24) &0xff) {        /* App4 is a multi-event event */
  476.                 case switchEvt:
  477.                     if (myEvent.message & 0x20)
  478.                         /*Convert clipboard here if necc. (it is not)*/;
  479.  
  480.                     if (myEvent.message & 0x1) {        /* Resume Event */
  481.                         GrafPtr window;
  482.  
  483.                         window = FrontWindow();    
  484.                         if ( (long)window != 0L) {
  485.                             myEvent.message = (long) window;
  486.                             myEvent.modifiers |= activeFlag;
  487.                             myEvent.what = activateEvt;
  488.                             myEvent.when = TickCount();
  489.                             SystemEvent( &myEvent);
  490.                         }
  491.                     }
  492.                     else {                                /* Suspend Event */
  493.                         GrafPtr window;
  494.  
  495.                         if ((window = FrontWindow())) {
  496.                             if ( (long)window != 0L) {
  497.                                 myEvent.message = (long) window;
  498.                                 myEvent.modifiers &= (~activeFlag);
  499.                                 myEvent.what = activateEvt;
  500.                                 myEvent.when = TickCount();
  501.                                 SystemEvent( &myEvent);
  502.                             }
  503.                         }
  504.                     }
  505.                     break;            /* switch of myEvent.message >>24 */
  506.                 }
  507.                 break;                /* switch app4evt */
  508.  
  509.             default:
  510.                 break;
  511.  
  512.         }/*endsw myEvent.what*/
  513.  
  514.     }/*endfor Main Event loop*/
  515.  
  516. /*
  517. *  Give windows back to the window manager.  Partially restores the color environment.
  518. */
  519.     mw = Mlist;
  520.     while (mw) {
  521.         DisposeWindow(mw->win);
  522.         mw = mw->next;
  523.     }
  524.     
  525.     stopnet();   /* NET */
  526. /*
  527. *  restore color settings - system level.
  528. */
  529.     colorrestore();
  530.  
  531.     return(0);                /* Return from main() to allow C runtime cleanup */
  532. }
  533.  
  534. void
  535. setupMenus()
  536. {
  537.     extern MenuHandle    MyMenus[];
  538.     register MenuHandle *pMenu;
  539.  
  540.     MyMenus[appleMenu] = GetMenu(appleID);
  541.     AddResMenu(MyMenus[appleMenu], (ResType) 'DRVR');
  542.     /*
  543.      * Now the File and Edit menus.
  544.      */
  545.     MyMenus[fileMenu] = GetMenu(fileID);
  546.     MyMenus[editMenu] = GetMenu(editID);
  547.     MyMenus[imageMenu] = GetMenu(imageID);
  548.     MyMenus[numMenu] = GetMenu(numID);
  549.     /*
  550.      * Now insert all of the application menus in the menu bar.
  551.      */
  552.     for (pMenu = &MyMenus[0]; pMenu < &MyMenus[menuCount]; ++pMenu) {
  553.         InsertMenu(*pMenu, 0);
  554.     }
  555.  
  556. #ifdef DEBUG
  557.     appendmenu( MyMenus[numMenu], "size" );
  558. #endif
  559.  
  560.     DrawMenuBar();
  561.  
  562.     return;
  563. }
  564.  
  565.  
  566. /******************************************************************/
  567. /* Disit and Enabit
  568. *  Disable or Enable a menu item with the new numbering scheme.
  569. *  Menu items are equal to 100 + the menu item number.
  570. */
  571. Disit(n)
  572.     int n;
  573. {
  574.     DisableItem(MyMenus[n / 100], n % 100);
  575. }
  576.  
  577. Enabit(n)
  578.     int n;
  579. {
  580.     EnableItem(MyMenus[n / 100], n % 100);
  581. }
  582.  
  583. /******************************************************************/
  584. /*  doCommand
  585.  * Process mouse clicks in menu bar.
  586.  *
  587.  */
  588. void
  589. doCommand(mResult)
  590. long mResult;
  591. {
  592.     extern MenuHandle    MyMenus[];
  593.     extern Boolean        DoneFlag;
  594.     int                 theMenu, theItem;
  595.     Str255                daName;
  596.     GrafPtr             savePort;
  597.  
  598.     theMenu = HIWORD(mResult);                    /* This is the resource ID */
  599.     theItem = LOWORD(mResult);
  600.     
  601.     switch (theMenu) {                            /* translation to menu array # */
  602.         case appleID:
  603.             if (theItem != MAbout_DataScope) {
  604.                 GetItem(MyMenus[appleMenu], theItem, daName);
  605.                 OpenDeskAcc(daName);
  606.             }
  607.             theMenu = 0;
  608.             break;
  609.         case fileID:
  610.             theMenu = 100;
  611.             break;
  612.         case editID:
  613.             /*
  614.              * If this is for a 'standard' edit item,
  615.              * run it through SystemEdit first.
  616.              * SystemEdit will return FALSE if it's not a system window.
  617.              */
  618.             if (SystemEdit(theItem-1)) {
  619.                 HiliteMenu(0);                    /* we are done, return */
  620.                 return;
  621.             }
  622.             theMenu = 200;
  623.             break;
  624.         case imageID:
  625.             theMenu = 300;
  626.             break;
  627.         case numID:
  628.             theMenu = 400;
  629.             break;
  630.     }
  631.     theItem += theMenu;
  632. /*
  633. *  theItem is a calculated unique ID for the menu selection.
  634. *  Menu*100 + item number.  Used to make the switch statement one level for
  635. *  convenience.
  636. */
  637.  
  638.     callmw = NULL;
  639.  
  640.     switch (theItem) {
  641.     case MAbout_DataScope:                /* About Dialog processing */
  642.         showAboutMeDialog();
  643.         break;
  644.  
  645.     case MOpen:
  646.         callme = openfloat;                /* Open an HDF file */
  647.         callmw = fmw;
  648.         break;
  649.  
  650.     case MClose:
  651.         callme = loseit;                /* Take away all windows associated with data */
  652.         callmw = fmw;
  653.         break;
  654.  
  655.     case MSave:                            /* Save the current window's dataset */
  656.     case MSave_As:
  657.         if (fmw) {
  658.             callme = saveit;
  659.             callmw = fmw;
  660.         }
  661.         break;
  662.         
  663.     case MLoad_Text:                    /* Load a Text file in */
  664.         callme = loadtext;
  665.         callmw = fmw;
  666.         break;
  667.         
  668.     case MQuit:                            /* Request exit */
  669.         DoneFlag = true;
  670.         /*
  671.         *  One last chance to save the datasets which we have.
  672.         */
  673.         mw = Mlist;
  674.         while (mw) {
  675.             if (mw->wintype == FTEXT) {
  676.                 if (checksave(mw)) {    /* user can save if he likes */
  677.                     DoneFlag = false;    /* cancel return, don't quit */
  678.                     break;
  679.                 }
  680.             }
  681.             mw = mw->next;
  682.         }
  683.         break;
  684.         
  685.     case MUndo:
  686.         break;
  687.         
  688.     case MCut:
  689.         if (fmw && fmw->wintype == FNOTES)
  690.             fmw->dat->needsave = 1;
  691.             /* fall through */
  692.     case MCopy:
  693.         if (fmw)
  694.         switch  (fmw->wintype) {
  695.         case FTEXT:
  696.             copyfloat(fmw);
  697.             break;
  698.         case FNOTES:
  699.             if (theItem == MCut) {
  700.                 TECut(fmw->nw->trec);
  701.             } else {
  702.                 TECopy(fmw->nw->trec);
  703.             }
  704.             ZeroScrap();
  705.             TEToScrap();
  706.             break;
  707.         default:
  708.             scrapimg(fmw);
  709.             break;
  710.         }
  711.         break;
  712.         
  713.     case MPaste:
  714.         if (fmw) {
  715.             if (fmw->wintype == FNOTES) {    /* paste text only to notebook window */
  716.                 fmw->dat->needsave = 1;
  717.                 TEFromScrap();
  718.                 TEPaste(fmw->nw->trec);
  719.             }
  720.             else {
  721.                 callme = dopaste;        /* paste image or data - will create new dataset */
  722.                 callmw = fmw;
  723.             }
  724.         }
  725.         else {
  726.             callme = dopaste;
  727.             callmw = NULL;
  728.         }
  729.         
  730.         break;
  731.  
  732.     case MClear:
  733.         if (fmw && fmw->wintype == FNOTES) {
  734.             fmw->dat->needsave = 1;
  735.             TEFromScrap();
  736.             TEDelete(fmw->nw->trec);
  737.         }
  738.         break;
  739.  
  740.     case MGenerate_Image:
  741.         if (fmw) {
  742.             callme = makeimage;
  743.             callmw = fmw;
  744.         }
  745.         break;
  746.         
  747.     case MInterpolated_Image:
  748.         if (fmw) {
  749.             callme = interpit;
  750.             callmw = fmw;
  751.         }
  752.         break;
  753.         
  754.     case MPolar_Image:
  755.         if (fmw) {
  756.             callme = polarit;
  757.             callmw = fmw;
  758.         }
  759.         break;
  760.         
  761.     case MLoad_Palette:
  762.             callme = loadpal;
  763.             callmw = fmw;                /* if null, the window pointer won't be used */
  764.         break;
  765.         
  766.     case MAttributes:
  767.         if (fmw) {
  768.             SetCursor(&qd.arrow);
  769.             callme = doatt;
  770.             callmw = fmw;
  771.         }
  772.         break;
  773.         
  774.     case MPolar_Size:
  775.         if (fmw) {
  776.             SetCursor(&qd.arrow);
  777.             callme = dopatt;
  778.             callmw = fmw;
  779.         }
  780.         break;
  781.         
  782.     case MImage_Size:
  783.         if (fmw) {
  784.             SetCursor(&qd.arrow);
  785.             callme = dosize;
  786.             callmw = fmw;
  787.         }
  788.         break;
  789.  
  790.     case MInterpolate_Size:
  791.         if (fmw) {
  792.             SetCursor(&qd.arrow);
  793.             callme = dosize;
  794.             callmw = fmw;
  795.         }
  796.         break;
  797.  
  798.     case MSynchronize:
  799.         if (fmw) {
  800.             callme = setsynch;
  801.             callmw = fmw;
  802.         }
  803.         break;
  804.         
  805.     case MExtract_Selection:            /* extract selection region */
  806.         if (fmw) {
  807.             callme = extit;
  808.             callmw = fmw;
  809.         }
  810.         break;    
  811.     
  812.     case MSee_Notebook:
  813.         if (fmw) {
  814.             callme = newnotes;
  815.             callmw = fmw;
  816.         }
  817.         break;
  818.         
  819.     case MCalculate_From_Notes:
  820.         if (fmw && fmw->wintype == FNOTES) {
  821.             callme = calcnotes;
  822.             callmw = fmw;
  823.         }
  824.         break;
  825.  
  826.     default:
  827.         break;
  828.  
  829.     }/*endsw theMenu*/
  830.  
  831. #ifdef DEBUG
  832.     { int i;
  833.     char s[256];
  834.     sprintf(s, "%d", MaxMem( &i ) );
  835.     setitem( MyMenus[numMenu], 7, s);
  836.     }
  837. #endif
  838.  
  839.     HiliteMenu(0);
  840.  
  841.     return;
  842. }
  843.  
  844. /************************************************************************************/
  845. /*  findm
  846. *   Find which Mac window is associated with the given window pointer.  Returns the
  847. *   Mwin pointer which contains that Mac window.
  848. */
  849. struct Mwin 
  850. *findm(thewin)
  851.     WindowPtr thewin;
  852.     {
  853.     struct Mwin *m;
  854.     
  855.     m = Mlist;
  856.     
  857.     while (m) {
  858.         if (m->win == thewin)
  859.             return(m);
  860.         m = m->next;
  861.     }
  862.     
  863.     return(NULL);
  864. }
  865.  
  866. /************************************************************************************/
  867. /*  calcnotes
  868. *   Calculate the value of the expression given and create a new text window for 
  869. *   the answer.
  870. */
  871. TEHandle lastte;
  872.  
  873. calcnotes(tw)
  874.     struct Mwin *tw;
  875.     {
  876.     int ret;
  877.     TEPtr tp;
  878.     extern char *expstr;
  879.     extern int explen;
  880.     char *p;
  881.     
  882.     lastte = tw->nw->trec;
  883.  
  884.     p = (char *) NewPtr(40000);
  885.     if (!p) {
  886.         char s[100];
  887.         sprintf(s,"\n** Out of memory **\n");
  888.         tp = *tw->nw->trec;            /* TErec */
  889.         TESetSelect(tp->selEnd, tp->selEnd, tw->nw->trec);
  890.         TEInsert( s, strlen(s), tw->nw->trec);
  891.         return;
  892.     }
  893.     DisposPtr(p);
  894. /*
  895. *  calculate selection size from the values in the TE record
  896. */
  897.     tp = *tw->nw->trec;                /* TErec */
  898.     explen = tp->selEnd - tp->selStart;
  899.  
  900.     HLock(tp->hText);                /* lock text handle */
  901.     expstr = *tp->hText;            /* get pointer */
  902.     expstr += tp->selStart;            /* move pointer to access selection region */
  903.  
  904. /*
  905. *  If the selection region is nil, use the current line.
  906. */
  907.     if (explen <= 0) {
  908.         p = expstr = *tp->hText + tp->selStart;        /* string in text field */
  909.         if (tp->selStart > 0)                        /* not at start, go back one */
  910.             --expstr;
  911.         while (expstr > *tp->hText && *expstr != '\n')
  912.             --expstr;
  913.         while (*p != '\n' && p < *tp->hText + tp->teLength)
  914.             p++;
  915.         explen = p - expstr;
  916.         TESetSelect(p - *tp->hText, p - *tp->hText, tw->nw->trec);
  917.     }
  918.     
  919.     if (explen <= 0 || explen > 20000) {
  920.         HUnlock(tp->hText);
  921.         return;
  922.     }
  923.  
  924. /*
  925. *  at this point, the starting pointer and len are set for access by the parser.
  926. *  Parser should not modify anything about the pointed-to data.
  927. */
  928.     ret = execit();                /* call yacc-derived parser and executer */
  929.     
  930.     tp = *tw->nw->trec;            /* TErec */
  931.     HUnlock(tp->hText);        
  932.     
  933.     SetCursor(&qd.arrow);
  934.     
  935.     if (ret) {                    /* error return from execit */
  936.         char s[100];
  937.         if (ret < 0)
  938.             sprintf(s,"\n**Parsing error.\n");
  939.         else
  940.             sprintf(s,"\n**Error in calculation.\n");
  941.  
  942.         tp = *tw->nw->trec;                /* TErec */
  943.         TESetSelect(tp->selEnd, tp->selEnd, tw->nw->trec);
  944.         TEInsert( s, strlen(s), tw->nw->trec);
  945.     }
  946.     
  947.  
  948. }
  949.  
  950. /************************************************************************************/
  951. /* ans_const
  952. *  If the calculation result is a constant, then we get a call back.
  953. */
  954. ans_const(v)
  955.     float v;
  956.     {
  957.     char s[100];
  958.     
  959.     sprintf(s,"\nResult: %f\n",v);
  960.     TESetSelect((*lastte)->selEnd, (*lastte)->selEnd, lastte);
  961.     TEInsert( s, strlen(s), lastte);
  962.     
  963. }
  964.  
  965. /************************************************************************************/
  966. /*  newnotes
  967. *  create a new notes window for the current window.  Can be any window with an 
  968. *  associated dataset.
  969. */
  970. newnotes(tw)
  971.     struct Mwin *tw;
  972.     {
  973.     struct Mwin *tempw;
  974.     struct fdatawin *td;
  975.     struct fnotewin *tn;
  976.     
  977. /*
  978. *  must have a data var
  979. */
  980.     if (!tw->dat)
  981.         return;
  982. /*
  983. *  if it already has a notes window, bring it to the front
  984. */
  985.     if (tw->dat->notes)    {
  986.         SelectWindow(tw->dat->notes->win);
  987.         return;
  988.     }
  989. /*
  990. *  link up new window into win list.
  991. */
  992.     tempw = (struct Mwin *)NewPtr(sizeof(struct Mwin));
  993.     if (!tempw)
  994.         return;
  995.         
  996.     tempw->dat = tw->dat;            /* point to same dataset */
  997.     tempw->dat->refcount++;            /* increase refcount bookkeeping */
  998.     tempw->nw = (struct fnotewin *)NewPtr(sizeof(struct fnotewin));
  999.     
  1000.     tempw->next = tw->next;            /* install in list */
  1001.     tw->next = tempw;
  1002.     tw = tempw;                        /* move to this element of list */
  1003.     
  1004.     tw->dat->notes = tw;            /* back pointer for text references */
  1005.     tw->wintype = FNOTES;            /* indicate the notes type flag */
  1006.     
  1007.     td = tw->dat;                    /* help for later de-referencing */
  1008.     tn = tw->nw;                    /* image window stuff */
  1009.     
  1010.     if (NULL == (tw->win = GetNewCWindow(imgwinID, NULL, (WindowPtr) -1)))
  1011.         return;
  1012.  
  1013.     setwtitle(tw->win,td->dvar);            /* a meaningful window title */
  1014.     
  1015.     MoveWindow(tw->win,startwin.h,startwin.v,false);
  1016.     newstartwin();
  1017.  
  1018.     ShowWindow(tw->win);
  1019.     SelectWindow(tw->win);
  1020.     SetPort(tw->win);
  1021.  
  1022.     tn->vis = tw->win->portRect;            /* rectangle definition in window */
  1023.     InsetRect(&tn->vis, 4, 0);
  1024.     tn->trec = TENew(&tn->vis, &tn->vis);    /* Not growable, so destRect == viewRect */
  1025.     
  1026. /*
  1027. *  Set up existing notebook contents into the textedit record.
  1028. */
  1029.     if (tw->dat->content) {                    /* we have some saved notes */
  1030.         (*tn->trec)->hText = (Handle) tw->dat->content;
  1031.         (*tn->trec)->teLength = tw->dat->contentlen;
  1032.         tw->dat->content = NULL;
  1033.         TECalText(tn->trec);
  1034.     }
  1035.     
  1036.     TESetSelect(0,0,tn->trec);                /* set selection to beginning */
  1037.     TEAutoView(true, tn->trec);                /* set autoscroll */
  1038.  
  1039. }
  1040.  
  1041. /************************************************************************************/
  1042. /*  emptyimage
  1043. *   Take a dataset and create a blank image window for that dataset.
  1044. *   Needs to know what type of image will be placed in here.
  1045. */
  1046.  
  1047. emptyimage(tw,wtype)
  1048.     struct Mwin *tw;
  1049.     int wtype;                        /* FIMG, FBI, FPOL */
  1050.     {
  1051.     struct Mwin *keepw,*tempw;
  1052.     int winwide,wintall,virtualwide,virtualtall;
  1053.     struct fdatawin *td;
  1054.     
  1055.     if (!tw->dat)
  1056.         return;
  1057.         
  1058.     keepw = tw;                        /* need a copy for later insertion into list */
  1059.  
  1060.     td = tw->dat;                    /* help for later de-referencing */
  1061.  
  1062.     tempw = (struct Mwin *)NewPtr(sizeof(struct Mwin));
  1063.     if (!tempw)
  1064.         return(-1);
  1065.         
  1066.     tempw->dat = tw->dat;            /* point to same dataset */
  1067.     tempw->dat->refcount++;            /* increase refcount bookkeeping */
  1068.     tw = tempw;                        /* move to this element of list */
  1069.     
  1070.     tw->wintype = wtype;            /* indicate the image type flag */
  1071.  
  1072.     switch (wtype) {
  1073.         case FIMG:
  1074.             if (checkmem(td->xdim*td->exx*td->ydim*td->exy+1000))
  1075.                 return(-1);
  1076.             tw->iw = (struct fimgwin *)NewPtr(sizeof(struct fimgwin));    
  1077.             tw->dat->image = tw;                    /* back pointer for text references */
  1078.             SetRect(&tw->iw->xr,-11,-11,-11,-11);    /* flag that box isn't set yet */
  1079.             tw->iw->exx = td->exx;
  1080.             tw->iw->exy = td->exy;
  1081.             tw->iw->xsize = winwide = td->xsize;
  1082.             tw->iw->ysize = wintall = td->ysize;
  1083.             virtualwide = td->xdim;
  1084.             virtualtall = td->ydim;
  1085.             break;
  1086.         case FBI:
  1087.             if (checkmem(td->xdim*td->exx*td->ydim*td->exy+1000))
  1088.                 return(-1);
  1089.             tw->bw = (struct fbiwin *)NewPtr(sizeof(struct fbiwin));    
  1090.             tw->dat->interp = tw;                    /* back pointer for text references */
  1091.             SetRect(&tw->bw->xr,-11,-11,-11,-11);    /* flag that box isn't set yet */
  1092.             tw->bw->exx = td->exx;
  1093.             tw->bw->exy = td->exy;
  1094.             winwide = virtualwide = tw->bw->xsize = td->xsize;
  1095.             wintall = virtualtall = tw->bw->ysize = td->ysize;
  1096.             break;
  1097.         case FPOL:
  1098.             if (checkmem(td->ydim*td->exx*td->ydim*td->exx+1000))
  1099.                 return(-1);
  1100.             tw->pw = (struct fpolwin *)NewPtr(sizeof(struct fpolwin));    
  1101.             tw->dat->polar = tw;                    /* back pointer for text references */
  1102.             SetRect(&tw->pw->xr,-11,-11,-11,-11);    /* flag that box isn't set yet */
  1103.             td->exy = td->exx;
  1104.             tw->pw->exx = td->exx;
  1105.             tw->pw->exy = td->exy;
  1106.             tw->pw->xsize = td->xsize;
  1107.             tw->pw->ysize = td->ysize;
  1108.             tw->pw->viewport = td->viewport;
  1109.             tw->pw->angleshift = td->angleshift;
  1110.             winwide = virtualwide = td->xsize = (td->viewport.right - td->viewport.left)*td->exx;
  1111.             wintall = virtualtall = td->ysize = (td->viewport.bottom - td->viewport.top)*td->exx;
  1112.             break;
  1113.         default:
  1114.             return(-1);
  1115.     }
  1116.     
  1117.     if ( 0 > blankimg(tw, &tw->vdev, winwide,wintall, virtualwide, virtualtall))
  1118.         return;                        /* set up window stuff */
  1119.  
  1120. /*
  1121. *  After getting this far, we know that the window belongs in the system list.
  1122. */
  1123.     tw->next = keepw->next;            /* install in list */
  1124.     keepw->next = tw;
  1125.     
  1126.     return(0);
  1127. }
  1128. /*
  1129.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1130.     makeimage        Generate an image from the data in the current float
  1131.                     window.  In this version, we force the xsize and
  1132.                     ysize to be a multiple of the array dimensions.
  1133.                     
  1134.                 tw = pointer to the Mwin structure
  1135.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1136. */
  1137. makeimage(tw)
  1138.     struct Mwin *tw;
  1139. {
  1140.     struct Mwin                *keepw,*tempw;
  1141.     register int            i,j;
  1142.     int                        wide,tall,down,oddone,spots,cmin,cmax,crange;
  1143.     register float            *f,invrange,tmin;
  1144.     register unsigned char    *p;
  1145.     unsigned char            *pstart;
  1146.     struct fdatawin            *td;
  1147.     struct fimgwin            *ti;
  1148.     void                    ErrorAlert();
  1149.     extern struct Mwin         *finddata ();
  1150.     extern struct Mwin         *findimage ();
  1151.  
  1152.     if (!tw->dat)
  1153.         return;
  1154.         
  1155.     keepw = tw;                        /* need a copy for later insertion into list */
  1156.     td = tw->dat;                    /* help for later de-referencing */
  1157.  
  1158.     if (td->image)    {
  1159.         /* did the interpolation size change. */
  1160.         
  1161.         tempw = findimage (tw);
  1162.         if (td->xsize != tempw->iw->xsize || td->ysize != tempw->iw->ysize) {
  1163.             if (td->image == tw)
  1164.                 keepw = tw = finddata (tw);
  1165.                 
  1166.             loseimage (td->image);
  1167.             td = tw->dat;
  1168.         } else {
  1169.             tw = td->image;
  1170.             setwtitle(tw->win,td->dvar);    /* could be a new window title */
  1171.             goto genimage;                /* nasty hack - we already have mem allocated */
  1172.         }    
  1173.     }    
  1174.  
  1175.     if (td->xsize < 50) {            /* minimum sizes for window to create */
  1176.         td->xsize = 50;
  1177.         td->exx = 50/td->xdim;
  1178.     }
  1179.     if (td->ysize < 50) {
  1180.         td->ysize = 50;
  1181.         td->exy = 50/td->ydim;
  1182.     }
  1183.  
  1184. /*
  1185. *  Are we going to have enough memory to do this?
  1186. */
  1187.  
  1188.     if (checkmem(td->xdim*td->ydim+2000))
  1189.        {ErrorAlert(GetResource('STR ',1001));
  1190.         return;
  1191.        }
  1192.  
  1193.     tempw = (struct Mwin *)NewPtr(sizeof(struct Mwin));
  1194.     if (!tempw)
  1195.        {ErrorAlert(GetResource('STR ',1001));
  1196.         return;
  1197.        }
  1198.         
  1199.     tempw->dat = tw->dat;            /* point to same dataset */
  1200.     tempw->dat->refcount++;            /* increase refcount bookkeeping */
  1201.     tempw->iw = (struct fimgwin *)NewPtr(sizeof(struct fimgwin));
  1202.     
  1203.     tw = tempw;                        /* move to this element of list */
  1204.     
  1205.     tw->dat->image = tw;            /* back pointer for text references */
  1206.     tw->wintype = FIMG;                /* indicate the image type flag */
  1207.     
  1208.     ti = tw->iw;                    /* image window stuff */
  1209.  
  1210.     SetRect(&ti->xr,-11,-11,-11,-11);                /* flag that box isn't set yet */
  1211.     ti->exx = td->exx;
  1212.     ti->exy = td->exy;
  1213.     ti->xsize = td->xsize = td->exx*td->xdim;        /* must be a multiple of dimension */
  1214.     ti->ysize = td->ysize = td->exy*td->ydim;
  1215.  
  1216.     if ( 0 > blankimg(tw,&tw->vdev, ti->xsize, ti->ysize, td->xdim, td->ydim))
  1217.        {ErrorAlert(GetResource('STR ',1016));
  1218.         return;
  1219.        }
  1220.     
  1221. /*
  1222. *  After getting this far, we know that the window belongs in the system list.
  1223. */
  1224.     tw->next = keepw->next;                            /* install in list */
  1225.     keepw->next = tw;
  1226.  
  1227. genimage:
  1228.     tall = td->ydim;
  1229.     wide = td->xdim;
  1230.     
  1231.     f = td->vals;                                    /* floating pt data */
  1232.     p = pstart = tw->vdev.bp;                        /* data space available */
  1233.     tmin = td->valmin;
  1234.     cmin = td->cmin;
  1235.     cmax = td->cmax;
  1236.     crange = td->cmax - td->cmin;
  1237.     invrange = 1.0/(td->valmax - tmin);
  1238.     if (invrange < 0) invrange = -invrange;            /* max must be > min */
  1239.     spots = 0;
  1240.     oddone = 0;
  1241.     if (wide & 1)
  1242.         oddone = 1;                                    /* has odd width */
  1243.     
  1244.     for (down=0; down < tall; down++) {
  1245.         
  1246.         if ((p - pstart) - spots*0x1000 > 0x1000) {    /* something for user to watch */
  1247.             SystemTask();
  1248.             if (calcidle())
  1249.                 down = tall;
  1250.             /* copyimg(tw); */
  1251.             spots++;
  1252.         }
  1253.  
  1254.         for (i = 0; i < wide; i++) {
  1255.  
  1256.             j = cmin + crange*(*f++ - tmin)*invrange;    /* cut scale a little short */
  1257.             if (j >= cmax || j < cmin)
  1258.                 *p++ = 0;
  1259.             else
  1260.                 *p++ = (char)j;
  1261.         }
  1262.         
  1263.         if (oddone)
  1264.             *p++ = 0;                                /* end of the line for odd width */
  1265.         
  1266.     }
  1267.     
  1268.     copyimg(tw);
  1269.     SetCursor(&qd.arrow);
  1270.     
  1271. }
  1272.  
  1273. /*******************************************************************************/
  1274. /*  blankimg
  1275. *   create a blank image window and a pixmap with palette.
  1276. */
  1277. blankimg(tw,vdev,xbig,ybig,xsp,ysp)
  1278.     struct Mwin *tw;
  1279.     VDevicePtr vdev;
  1280.     int xbig,ybig,xsp,ysp;
  1281.     {
  1282.     unsigned char *p;
  1283.     PaletteHandle pal;
  1284.     struct fdatawin *td;
  1285.     Rect tr;
  1286.     
  1287.     td = tw->dat;                                /* help for later de-referencing */
  1288.     
  1289.     SetRect(&tw->pref, 0,0, xsp,ysp);            /* preferred bounds rectangle */
  1290.     
  1291.     if (xsp & 1)
  1292.         xsp++;                                    /* odd width, add one */
  1293. /*
  1294. *  Try the big memory allocation first in case it fails.
  1295. */
  1296.     if (NULL == (p = (char *) NewPtr( xsp*ysp ))) {        /* room for bitmap */
  1297.         return(-1);
  1298.     }
  1299.     
  1300. /*
  1301. *  The window to display it in.
  1302. */
  1303.     if (NULL == (tw->win = GetNewCWindow(imgwinID, NULL, (WindowPtr) -1)))
  1304.         return(-1);
  1305.  
  1306.     SizeWindow(tw->win, xbig, ybig, false);
  1307.     setwtitle(tw->win,td->dvar);                /* a meaningful window title */
  1308.     
  1309.     MoveWindow(tw->win,startwin.h,startwin.v,false);
  1310.     newstartwin();
  1311.     ShowWindow(tw->win);
  1312. /*    SelectWindow(tw->win);
  1313.     
  1314. /*
  1315. *  create the palette for the window, will be all black before setpal
  1316. */
  1317.     pal = NewPalette(255, NULL, pmTolerant, 0);
  1318.     SetPalette( tw->win, pal, false);
  1319.     ActivatePalette(tw->win);
  1320.  
  1321.     SetRect(&tr, 0,0, xsp,ysp);            /* bounds rectangle */
  1322.     vdev->bounds = tr;
  1323.     vdev->bp = p;                        /* space for pixel storage */
  1324.  
  1325.     InitVDevice(vdev);                    /* the off-screen drawing space */
  1326.     
  1327.     setpal(tw, rgbsave);                /* init with saved global color table */
  1328.     
  1329.     SetPort(tw->win);
  1330.     EraseRect(&tr);
  1331.     
  1332. }    
  1333.  
  1334.  
  1335. /*******************************************************************************/
  1336. /*  setpal
  1337. *  Take a window and palette - set the colors for it and the off-screen device.
  1338. */
  1339. setpal(tw,rgb)
  1340.     struct Mwin *tw;
  1341.     unsigned char *rgb;
  1342.     {
  1343.     RGBColor curcol;
  1344.     register int i;
  1345.     register unsigned char *p;
  1346.     PaletteHandle pal;
  1347.     
  1348.     if (!tw || !tw->win ||
  1349.         (tw->wintype != FBI && tw->wintype != FIMG && tw->wintype != FPOL))
  1350.         return(-1);
  1351. /*
  1352. *  set up palette for window and off-screen device.
  1353. *  We assign a set of colors to indices inside the palette. 
  1354. *  By making the palette manager active, the colors needed for the window are always in
  1355. *  place when the window is frontmost.
  1356. *
  1357. */
  1358.     pal = GetPalette(tw->win);                    /* get existing palette */
  1359.     
  1360.     p = rgb;
  1361.     
  1362.     for (i=0; i<255; i++) {
  1363.         curcol.red = (*p++)<<8;
  1364.         curcol.green = (*p++)<<8;
  1365.         curcol.blue = (*p++)<<8;
  1366.         SetEntryColor( pal, i, &curcol);
  1367.     }
  1368.         
  1369.     SetPalette( tw->win, pal, true);            /* set new palette back */
  1370.     ActivatePalette(tw->win);
  1371.  
  1372. /*
  1373. *  apply the new colors to the hidden color table in the gdevice and cport.
  1374. */
  1375.     ColorVDevice(&tw->vdev,pal);
  1376.     
  1377.     return(0);
  1378.     
  1379. }
  1380.  
  1381. /*******************************************************************************/
  1382. /*  newstartwin
  1383. *   Update the variable which contains the location for the next upper left corner
  1384. *   starting position.
  1385. */
  1386. newstartwin()
  1387.     {
  1388.     startwin.h += 15;
  1389.     startwin.v += 20;
  1390.     if (startwin.v > 175)
  1391.          startwin.v = 50;
  1392.     if (startwin.h > 300) {
  1393.         startwin.v = 50;
  1394.         startwin.h = 20;
  1395.     }
  1396.          
  1397. }
  1398.  
  1399. /***************************************************************************************/
  1400. /*  setsynch
  1401. *  Set up the synch flag for the program.
  1402. */
  1403. setsynch(tw)
  1404.     struct Mwin *tw;
  1405.     {
  1406.     MenuHandle men;
  1407.             
  1408.     if (synchro)            /* what is current setting of synch parm?, flip it */
  1409.         synchro = 0;
  1410.     else 
  1411.         synchro = 1;
  1412.     
  1413.     men = GetMenu( numID );
  1414.     CheckItem(men, MSynchronize % 100, synchro);        /* show menu checkmark */
  1415.     
  1416. }
  1417.  
  1418. /***************************************************************************************/
  1419. /*  rmwin
  1420. *   Take a window out of the list.
  1421. */
  1422. rmwin(tw)
  1423.     struct Mwin *tw;
  1424.     {
  1425.     struct Mwin *oldw,*tmpw;
  1426.     
  1427.     if (Mlist == tw) {
  1428.         Mlist = tw->next;                        /* at top of the list */
  1429.     }
  1430.     else {
  1431.         tmpw = oldw = Mlist;
  1432.         while (tmpw = tmpw->next) {                /* search list */
  1433.             if (tmpw == tw) {                    /* got match */
  1434.                 oldw->next = tmpw->next;        /* remove it */
  1435.                 return;                            /* now done */
  1436.             }
  1437.             oldw = tmpw;
  1438.         }
  1439.     }
  1440.     
  1441. }
  1442.  
  1443. /***************************************************************************************/
  1444. /*  synchfloat
  1445. *   Call setfloat for each of the floating point windows which have the synch flag
  1446. *   on.  Will invalidate the display rects for those windows and change their selection
  1447. *   region to match this one.
  1448. */
  1449. synchfloat(tw,sr,metoo)
  1450.     struct Mwin *tw;
  1451.     Rect *sr;
  1452.     int metoo;
  1453.     {
  1454.         
  1455. /*
  1456. *  If synch is not on, we have a boring situation, check the metoo flag and update
  1457. *  the current float window (maybe) and the image window for that float window.
  1458. */
  1459.     if (!synchro) {
  1460.     /*
  1461.     *  no synchro set, so we do the littlebox for the image window 
  1462.     */
  1463.         if (tw->dat->image) 
  1464.             littlebox(tw->dat->image,sr,1);            /* draw that box */
  1465.         if (tw->dat->interp)
  1466.             littlebox(tw->dat->interp,sr,1);        /* draw that box */
  1467.         if (tw->dat->polar)
  1468.             littlesect(tw->dat->polar,sr,1);        /* draw in the polar window */
  1469.             
  1470.         if (metoo)
  1471.             setfloat(tw->dat->text,sr);                /* invalidate my window */
  1472.         return;
  1473.     }
  1474.  
  1475. /*
  1476. *  search list for matching windows and update them too.
  1477. */
  1478.     mw = Mlist;
  1479.     
  1480.     while (mw) {
  1481.         if ( mw->dat->xdim == tw->dat->xdim
  1482.             && mw->dat->ydim == tw->dat->ydim) {
  1483.             
  1484.             if (mw->wintype == FTEXT &&            /* unless suppressed with metoo, */
  1485.                 (metoo || tw != mw))            /* set new text selection in text win */
  1486.                 setfloat(mw,sr);
  1487.             else if (mw->wintype == FIMG ||
  1488.                 mw->wintype == FBI) {            /* do littlebox in all synched image wins */
  1489.                 littlebox(mw,sr,1);                /* draw that box */
  1490.             }
  1491.             else if (mw->wintype == FPOL)
  1492.                 littlesect(mw,sr,1);            /* draw in the polar window */
  1493.         }
  1494.             
  1495.             
  1496.         mw = mw->next;
  1497.     }
  1498. }
  1499.  
  1500. /***************************************************************************************/
  1501. /*  extit
  1502. *  Extract the current selection region and make a new text window out of it.
  1503. */
  1504. extit(tw)
  1505.     struct Mwin *tw;
  1506.     {
  1507.     struct ftextwin *tc;
  1508.     struct fdatawin *td,*extractdata();
  1509.     Rect tr;
  1510.     
  1511.     if (!tw->dat || !tw->dat->text)
  1512.         return;
  1513.         
  1514.     tc = tw->dat->text->cw;
  1515.     tr = tc->sel;
  1516.     if (tr.bottom - tr.top < 1 || tr.right - tr.left < 1 ||
  1517.         tr.top < 0 || tr.bottom < 0 ||
  1518.         tr.right < 0 || tr.left < 0)
  1519.         return;
  1520.     if (NULL == (td = extractdata(tw->dat,&tr)))    /* copies the data record */
  1521.         return;
  1522.     
  1523.     td->dvar[17] = '\0';                        /* make sure it is short enough */
  1524.     strcat(td->dvar,"_x");                        /* slightly modify variable name */
  1525.     
  1526.     ctextwin(td);                                /* creates the new text win */
  1527.  
  1528. }
  1529.  
  1530. /***************************************************************************************/
  1531. /*  calcidle
  1532. *   Show progress for calculations and check for command-period being used to abort 
  1533. *   the calculation.  Return 0 for ok status and 1 for user-abort.
  1534. */
  1535. int watchstate=0,nextidle=0;
  1536.  
  1537. calcidle()
  1538.     {
  1539.     EventRecord     myevent;
  1540. /*
  1541. *  give up a little system time
  1542. */
  1543.     SystemTask();
  1544.     
  1545. /*
  1546. *  If being called too soon after last time, just return.
  1547. */
  1548.     if (TickCount() < nextidle)
  1549.         return(0);
  1550.     
  1551.     nextidle = TickCount() + 30;             /* one-half second intervals */
  1552. /*
  1553. *  set spinning watch cursor 
  1554. */
  1555.     SetCursor(*spinwatch[watchstate]);
  1556.     watchstate = ++watchstate % 7;
  1557. /*
  1558. *  check keyboard for command-period which indicates a user-cancel command.
  1559. */
  1560.  
  1561.     if (GetNextEvent(keyDownMask, &myevent)) {                /* if we have a keydown event, */
  1562.         if (myevent.what == keyDown &&                        /* and event is keyboard */
  1563.             (myevent.modifiers & cmdKey) &&                    /* and command is held down */
  1564.             (myevent.message & charCodeMask) == '.')        /* and is a period */
  1565.             return(1);                                        /* stop the processing */
  1566.     }
  1567.     
  1568.     return(0);
  1569. }
  1570.  
  1571.  
  1572. /***************************************************************************************/
  1573. /*  saveit
  1574. *   Save the current text window's data and configuration so that the open command
  1575. *   will automatically get it back.
  1576. */
  1577. saveit(tw)
  1578.     struct Mwin *tw;
  1579.     {
  1580.     SFReply reply;
  1581.      Point wh;
  1582.     int reccr = 'NCSf',rectype = '_HDF';
  1583.  
  1584.     wh.h = wh.v = 50;
  1585.     sfputfile(&wh, "Name for saved HDF file", tw->dat->fname, nil, &reply);
  1586.     if (reply.good) {
  1587.         p2cstr(reply.fName);
  1588.         setvol(NULL, reply.vRefNum);            /* set to this volume (dir) */
  1589.         
  1590. /*
  1591. *  create the file with FScreate
  1592. */
  1593.         create(reply.fName, reply.vRefNum, reccr, rectype);
  1594.  
  1595.         savedf(reply.fName, tw->dat);            /* write the data into it */
  1596.         return(0);
  1597.     }
  1598.     
  1599.     return(-1);    
  1600. }
  1601.  
  1602. /***************************************************************************/
  1603. /*  set greys for current mlist state.
  1604. */
  1605. char greyon=1;
  1606.  
  1607. setgreys()
  1608.     {
  1609.     
  1610.     if (greyon && !Mlist) {            /* if we are turning them off */    
  1611.         Disit(MClose);
  1612.         Disit(MSave);
  1613.         Disit(MSave_As);
  1614.         Disit(MGenerate_Image);
  1615.         Disit(MInterpolated_Image);
  1616.         Disit(MPolar_Image);
  1617.         Disit(MAttributes);
  1618.         Disit(MImage_Size);
  1619.         Disit(MInterpolate_Size);
  1620.         Disit(MPolar_Size);
  1621.         Disit(MSynchronize);
  1622.         Disit(MExtract_Selection);
  1623.         Disit(MSee_Notebook);
  1624.         Disit(MCalculate_From_Notes);
  1625.  
  1626.         greyon = 0;
  1627.     }
  1628.     else if (!greyon && Mlist) {    /* if we are turning them on */
  1629.         Enabit(MClose);
  1630.         Enabit(MSave);
  1631.         Enabit(MSave_As);
  1632.         Enabit(MGenerate_Image);
  1633.         Enabit(MInterpolated_Image);
  1634.         Enabit(MPolar_Image);
  1635.         Enabit(MAttributes);
  1636.         Enabit(MImage_Size);
  1637.         Enabit(MInterpolate_Size);
  1638.         Enabit(MPolar_Size);
  1639.         Enabit(MSynchronize);
  1640.         Enabit(MExtract_Selection);
  1641.         Enabit(MSee_Notebook);
  1642.         
  1643.         greyon = 1;
  1644.     }
  1645.  
  1646. }
  1647.  
  1648. /***************************************************************************/
  1649. /*  colorsave and colorrestore
  1650. *  save and restore the color state of the current gdevice.
  1651. */
  1652.  
  1653. struct {
  1654.     short size;
  1655.     short reqdata[260];
  1656. } sel;
  1657.  
  1658. CTabHandle gtab;
  1659.  
  1660. colorsave()
  1661.     {
  1662.     int i;
  1663.     
  1664.     sel.size = 255;
  1665.     for (i=0; i<256; i++)
  1666.         sel.reqdata[i] = i;
  1667.     
  1668. /*
  1669. *  extra space gives room for the Ctab struct
  1670. */
  1671.     gtab = (CTabHandle)NewHandle(260*sizeof(ColorSpec)); 
  1672.     
  1673.     SaveEntries( NULL, gtab, (ReqListRec *) &sel);
  1674.     
  1675. }
  1676.  
  1677. colorrestore()
  1678.     {
  1679.     CGrafPtr cgp;
  1680.     
  1681.     WindowPtr cw;
  1682.  
  1683.     RestoreEntries(gtab, NULL, (ReqListRec *) &sel);
  1684.  
  1685.     cw = newcwindow(nil, &qd.screenBits.bounds, "Restoring Colors", true,
  1686.         2, nil, false, 0);
  1687.  
  1688. /*
  1689. *  We created a color window.
  1690. *  Now we change the color table seed value so that the color environment must reset
  1691. *  itself when the window is disposed.
  1692. *
  1693. *  We had to create the color window the size of the screen because it must invalidate the
  1694. *  background and all of the other windows under multifinder.  To date, they are too stupid
  1695. *  to remember to update themselves when the color environment changes back.
  1696. *
  1697. *  This means that there is, in effect a "color" update region.  That region where the
  1698. *  windows must re-draw themselves to get the right colors back.  When we are done, we do
  1699. *  so much damage that that region must become the whole screen.
  1700. */
  1701.     cgp = (CGrafPtr) cw;
  1702.     (*((*(cgp->portPixMap))->pmTable))->ctSeed = GetCTSeed();
  1703.     
  1704.     DisposeWindow(cw);
  1705.  
  1706. }
  1707. #define    GENALRT             500
  1708. /*
  1709.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1710.     ErrorAlert        This routine will display an alert box and insert in
  1711.                     it the passed string
  1712.                     
  1713.                 s = handle to the char string
  1714.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1715. */
  1716. void ErrorAlert (s)
  1717.     char        **s;
  1718. {
  1719.     ParamText (*s, "", "", "");
  1720.     StopAlert ((short) GENALRT, NULL);
  1721.  
  1722.     return;
  1723. }
  1724.